package com.harmonyos.zxing;

import com.google.zxing.client.ohos.Intents;
import com.google.zxing.integration.ohos.IntentIntegrator;
import com.google.zxing.integration.ohos.IntentResult;
import ohos.aafwk.ability.fraction.Fraction;
import ohos.aafwk.ability.fraction.FractionAbility;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.LayoutScatter;
import ohos.agp.window.dialog.ToastDialog;
import ohos.media.camera.CameraKit;
import ohos.media.camera.device.CameraInfo;

import java.util.logging.Logger;

import static com.google.zxing.integration.ohos.IntentIntegrator.REQUEST_CODE;

public class MainAbility extends FractionAbility implements Component.ClickedListener {
    private static final String TAG = "MainAbility";
    public final int CUSTOMIZED_REQUEST_CODE = 0x0000ffff;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        setUIContent(ResourceTable.Layout_ability_main);

        DirectionalLayout directionalLayout = (DirectionalLayout) findComponentById(ResourceTable.Id_directionalLayout);
        int childCount = directionalLayout.getChildCount();
        for (int i = 0; i < childCount; i++) {
            directionalLayout.getComponentAt(i).setClickedListener(this);
        }

        getFractionManager().startFractionScheduler().add(ResourceTable.Id_fraction_scan,new ScanFraction()).submit();
    }


    @Override
    public void onClick(Component component) {
        switch (component.getId()) {
            case ResourceTable.Id_scan_barcode:
                scanBarcode(component);
                break;
            case ResourceTable.Id_PDF417:
                scanPDF417(component);
                break;
            case ResourceTable.Id_scan_barcode_with_request_code:
                scanBarcodeWithCustomizedRequestCode(component);
                break;
            case ResourceTable.Id_scan_Inverted:
                scanBarcodeInverted(component);
                break;
            case ResourceTable.Id_scan_Normal_Inverted:
                scanMixedBarcodes(component);
                break;
            case ResourceTable.Id_any_orientation:
                scanBarcodeCustomLayout(component);
                break;
            case ResourceTable.Id_front_camera:
                scanBarcodeFrontCamera(component);
                break;
            case ResourceTable.Id_custom_activity:
                scanContinuous(component);
                break;
            case ResourceTable.Id_toolbar_activity:
                scanToolbar(component);
                break;
            case ResourceTable.Id_custom_scanner:
                scanCustomScanner(component);
                break;
            case ResourceTable.Id_scanner_with_margin:
                scanMarginScanner(component);
                break;
            case ResourceTable.Id_scanner_with_timeout:
                scanWithTimeout(component);
                break;
            case ResourceTable.Id_tabs:
                tabs(component);
                break;
        }
    }

    public void scanBarcode(Component view) {
        new IntentIntegrator(this).initiateScan();
    }

    public void scanBarcodeWithCustomizedRequestCode(Component view) {
        new IntentIntegrator(this).setRequestCode(CUSTOMIZED_REQUEST_CODE).initiateScan();
    }

    public void scanBarcodeInverted(Component view) {
        IntentIntegrator integrator = new IntentIntegrator(this);
        integrator.addExtra(Intents.Scan.SCAN_TYPE, Intents.Scan.INVERTED_SCAN);
        integrator.initiateScan();
    }

    public void scanMixedBarcodes(Component view) {
        IntentIntegrator integrator = new IntentIntegrator(this);
        integrator.addExtra(Intents.Scan.SCAN_TYPE, Intents.Scan.MIXED_SCAN);
        integrator.initiateScan();
    }

    public void scanBarcodeCustomLayout(Component view) {
        IntentIntegrator integrator = new IntentIntegrator(this);
        integrator.setDesiredBarcodeFormats(IntentIntegrator.ONE_D_CODE_TYPES);
        integrator.setPrompt("Scan something");
        integrator.setOrientationLocked(false);
        integrator.setBeepEnabled(false);
        integrator.initiateScan();
    }

    public void scanPDF417(Component view) {
        IntentIntegrator integrator = new IntentIntegrator(this);
        integrator.setDesiredBarcodeFormats(IntentIntegrator.PDF_417);
        integrator.setPrompt("Scan something");
        integrator.setOrientationLocked(false);
        integrator.setBeepEnabled(false);
        integrator.initiateScan();
    }


    public void scanBarcodeFrontCamera(Component view) {
        IntentIntegrator integrator = new IntentIntegrator(this);
        CameraKit cameraKit = CameraKit.getInstance(this);
        String[] cameraIds = cameraKit.getCameraIds();
        String cameraId = null;
        for (String cid:cameraIds) {
            CameraInfo cameraInfo = cameraKit.getCameraInfo(cid);
            if (cameraInfo.getFacingType() == CameraInfo.FacingType.CAMERA_FACING_FRONT) {
                cameraId = cid;
                break;
            }
        }
        if (cameraId == null) {
            Logger.getLogger(TAG).severe("no camera facing front");
        }
        integrator.setCameraId(cameraId);
        integrator.initiateScan();
    }

    public void scanContinuous(Component view) {
        Intent intent = new Intent();
        Operation operation = new Intent.OperationBuilder()
                .withBundleName(getBundleName())
                .withAbilityName(ContinuousCaptureAbility.class.getName())
                .build();
        intent.setOperation(operation);
        startAbility(intent);
        setTransitionAnimation(-1,-1);
    }

    public void scanToolbar(Component view) {
        new IntentIntegrator(this).setCaptureActivity(ToolbarCaptureAbility.class).initiateScan();
    }

    public void scanCustomScanner(Component view) {
        new IntentIntegrator(this).setOrientationLocked(false).setCaptureActivity(CustomScannerAbility.class).initiateScan();
    }

    public void scanMarginScanner(Component view) {
        IntentIntegrator integrator = new IntentIntegrator(this);
        integrator.setOrientationLocked(false);
        integrator.setCaptureActivity(SmallCaptureAbility.class);
        integrator.initiateScan();
    }

    public void scanWithTimeout(Component view) {
        IntentIntegrator integrator = new IntentIntegrator(this);
        integrator.setTimeout(8000);
        integrator.initiateScan();
    }

    public void tabs(Component view) {
        Intent intent = new Intent();
        Operation operation = new Intent.OperationBuilder()
                .withBundleName(getBundleName())
                .withAbilityName(TabbedScanning.class.getName())
                .build();
        intent.setOperation(operation);
        startAbility(intent);
        setTransitionAnimation(-1,-1);
    }

    @Override
    protected void onAbilityResult(int requestCode, int resultCode, Intent data) {

        if (requestCode != CUSTOMIZED_REQUEST_CODE && requestCode != REQUEST_CODE) {
            // This is important, otherwise the result will not be passed to the fragment
            super.onAbilityResult(requestCode, resultCode, data);
            return;
        }
        switch (requestCode) {
            case CUSTOMIZED_REQUEST_CODE: {
                new ToastDialog(this).setText("REQUEST_CODE = " + requestCode)/*.setDuration(3000)*/.show();
                break;
            }
            case REQUEST_CODE: {
                IntentResult result = IntentIntegrator.parseAbilityResult(requestCode, resultCode, data);
                if (result != null) {
                    String toast;
                    if (result.getContents() == null) {
                        toast = "Cancelled from fragment";
                    } else {
                        toast = "Scanned from fragment: " + result.getContents();
                    }

                    // At this point we may or may not have a reference to the activity
                    displayToast(toast);
                }
                return;
            }
            default:
                break;
        }

        IntentResult result = IntentIntegrator.parseAbilityResult(resultCode, data);

        if (result.getContents() == null) {
            Intent originalIntent = result.getOriginalIntent();
            if (originalIntent == null) {
                new ToastDialog(this).setText("Cancelled").setDuration(3000).show();
            } else if (originalIntent.hasParameter(Intents.Scan.MISSING_CAMERA_PERMISSION)) {
                new ToastDialog(this).setText("Cancelled due to missing camera permission").setDuration(3000).show();
            }
        } else {
            new ToastDialog(this).setText("Scanned: " + result.getContents())/*.setDuration(3000)*/.show();
        }
    }

    private void displayToast(String toast) {
        new ToastDialog(this).setText(toast)/*.setDuration(3000)*/.show();
    }

    public static class ScanFraction extends Fraction {
        @Override
        protected Component onComponentAttached(LayoutScatter scatter, ComponentContainer container, Intent intent) {
            Component component = scatter.parse(ResourceTable.Layout_fraction_scan, container, false);
            Component fractionScan = component.findComponentById(ResourceTable.Id_scan_from_fraction);
            fractionScan.setClickedListener(new Component.ClickedListener() {
                @Override
                public void onClick(Component component) {
                    IntentIntegrator.forSupportFragment(ScanFraction.this).initiateScan();
                }
            });
            return component;
        }


    }
}
